/*
 *
 * Copyright (C) 2012 Walter Lütgenau
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 */
package offset.nodes.client.vdialog.model.template;

import java.io.StringReader;
import java.util.LinkedList;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.xml.parsers.SAXParserFactory;
import offset.nodes.Constants;
import offset.nodes.client.model.NodeTypes;
import offset.nodes.client.model.SimpleNamespaceRegistry;
import offset.nodes.client.model.StringArrayConverter;
import offset.nodes.client.virtual.model.jcr.QName;
import offset.nodes.client.veditor.model.messages.TemplateEditorResult;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

/**
 *
 * @author Walter Lütgenau
 */
public class TemplateDefinitionReader implements ContentHandler {

    DefaultMutableTreeNode root;
    DefaultMutableTreeNode current;
    AbstractTemplateNode currentNode;
    TemplateNodeNode templateNode;
    String data;
    NodeTypes types;

    class TemplateNodeNode {

        String uuid;
        String name;
        String query;
        String[] secondaryQueries;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getUuid() {
            return uuid;
        }

        public void setUuid(String uuid) {
            this.uuid = uuid;
        }

        public String getQuery() {
            return query;
        }

        public void setQuery(String query) {
            this.query = query;
        }

        public String[] getSecondaryQueries() {
            return secondaryQueries;
        }

        public void setSecondaryQueries(String[] secondaryQueries) {
            this.secondaryQueries = secondaryQueries;
        }

    }

    public TemplateDefinitionReader(NodeTypes types) {
        this.types = types;
    }

    public void parse(String templateDefinitions) {
        try {
            XMLReader reader = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
            reader.setContentHandler(this);
            reader.parse(new InputSource(new StringReader(templateDefinitions)));
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public DefaultMutableTreeNode getRoot() {
        return root;
    }

    String getName(String uri, String localName, String qName) {
        return qName;
    }

    String getAttribute(Attributes atts, String name) {
        return atts.getValue("", name);
    }

    public void characters(char[] ch, int start, int length) throws SAXException {
    }

    public void endDocument() throws SAXException {
    }

    public void endElement(String uri, String localName, String qName) throws SAXException {
        String name = getName(uri, localName, qName);
        if ( name.equals(Constants.CHILD_SAMPLE)) {
            PageNode page = (PageNode) current.getUserObject();
            page.getPage().setSampleHtml(data);
        }
        else if ( name.equals(Constants.CHILD_TRANSFORMATION)) {
            PageNode page = (PageNode) current.getUserObject();
            page.getPage().setStyleSheet(data);
        }
        else if ( name.equals(Constants.CHILD_EDITORTRANSFORMATION)) {
            PageNode page = (PageNode) current.getUserObject();
            page.getPage().setEditorStyleSheet(data);
        }
        else if ( name.equals(Constants.CHILD_CSS)) {
            PageNode page = (PageNode) current.getUserObject();
            page.getPage().setCascadingStyleSheet(data);
        }
            
    }

    public void endPrefixMapping(String prefix) throws SAXException {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void processingInstruction(String target, String data) throws SAXException {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void setDocumentLocator(Locator locator) {
    }

    public void skippedEntity(String name) throws SAXException {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void startDocument() throws SAXException {
    }

    protected TemplateNode createTemplate(Attributes atts) {
        TemplateNode template = new TemplateNode();

        template.setUuid(getAttribute(atts, Constants.JCR_UUID));
        template.setName(getAttribute(atts, Constants.PROP_NAME));        

        return template;
    }

    protected void setTemplateNode(Attributes atts) {
        templateNode = new TemplateNodeNode();

        templateNode.setUuid(getAttribute(atts, Constants.JCR_UUID));
        templateNode.setName(getAttribute(atts, Constants.PROP_NAME));
        templateNode.setQuery(getAttribute(atts, Constants.PROP_PRIMARY_QUERY));
        
        String query = null;
        if ( (query = getAttribute(atts, Constants.PROP_SECONDARY_QUERY)) != null) {
            StringArrayConverter sa = new StringArrayConverter(query);
            templateNode.setSecondaryQueries(sa.toArray());
        }
    }

    protected FolderNode createFolder(Attributes atts) {
        FolderNode folder = new FolderNode();

        folder.setUuid(templateNode.getUuid());
        folder.setQuery(templateNode.getQuery());
        folder.setRepresentationUuid(getAttribute(atts, Constants.JCR_UUID));
        String nodeTypeName = getAttribute(atts, Constants.PROP_NODETYPE);
        if ( nodeTypeName != null)
            folder.setNodeType( types.get(QName.valueOf(SimpleNamespaceRegistry.getInstance().toQNameString(nodeTypeName))));
        folder.setType(getAttribute(atts, Constants.JCR_PRIMARY_TYPE));
        folder.setName(getAttribute(atts, Constants.PROP_NAME));
        folder.setNameProperty(getAttribute(atts, Constants.PROP_NAME_PROPERTY));

        return folder;
    }

    protected PageNode createPage(Attributes atts) {
        PageNode page = new PageNode();

        page.setUuid(templateNode.getUuid());
        page.setQuery(templateNode.getQuery());
        page.setRepresentationUuid(getAttribute(atts, Constants.JCR_UUID));
        String nodeTypeName = getAttribute(atts, Constants.PROP_NODETYPE);
        if ( nodeTypeName != null)
            page.setNodeType( types.get(QName.valueOf(SimpleNamespaceRegistry.getInstance().toQNameString(nodeTypeName))));
        page.setPage(new TemplateEditorResult());
        page.getPage().setSecondaryQueries(templateNode.getSecondaryQueries());
        page.setType(getAttribute(atts, Constants.JCR_PRIMARY_TYPE));
        page.setName(getAttribute(atts, Constants.PROP_NAME));
        page.setNameProperty(getAttribute(atts, Constants.PROP_NAME_PROPERTY));

        return page;
    }

    public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
        String type = getAttribute(atts, Constants.JCR_PRIMARY_TYPE);

        if (type.equals(Constants.TYPE_TEMPLATE))
            current = root = new DefaultMutableTreeNode(createTemplate(atts));
        else if (type.equals(Constants.TYPE_TEMPLATE_NODE))
            setTemplateNode(atts);
        else if (type.equals(Constants.TYPE_VIRTUAL_FOLDER)) {
            DefaultMutableTreeNode child = new DefaultMutableTreeNode(createFolder(atts));
            current.add(child);
            current = child;
        }
        else if (type.equals(Constants.TYPE_VIRTUAL_PAGE)) {
            DefaultMutableTreeNode child = new DefaultMutableTreeNode(createPage(atts));
            current.add(child);
            current = child;
        }
        else if ( getName(uri,localName,qName).equals(Constants.CHILD_SAMPLE)) {
            PageNode page = (PageNode) current.getUserObject();
            page.setSampleUuid(getAttribute(atts,Constants.JCR_UUID));
        }
        else if ( getName(uri,localName,qName).equals(Constants.CHILD_CSS)) {
            PageNode page = (PageNode) current.getUserObject();
            page.setCssUuid(getAttribute(atts,Constants.JCR_UUID));
        }
        else if ( getName(uri,localName,qName).equals(Constants.NODES_BODY)) {
            PageNode page = (PageNode) current.getUserObject();
            page.setCssBodyUuid(getAttribute(atts,Constants.JCR_UUID));
        }
        else if ( getName(uri,localName,qName).equals(Constants.CHILD_TRANSFORMATION)) {
            PageNode page = (PageNode) current.getUserObject();
            page.setTransformationUuid(getAttribute(atts,Constants.JCR_UUID));
        }
        else if ( getName(uri,localName,qName).equals(Constants.CHILD_EDITORTRANSFORMATION)) {
            PageNode page = (PageNode) current.getUserObject();
            page.setEditorTransformationUuid(getAttribute(atts,Constants.JCR_UUID));
        }
        else if (getName(uri, localName, qName).equals(Constants.JCR_CONTENT)) 
            data = getAttribute(atts, Constants.JCR_DATA);
            
    }

    public void startPrefixMapping(String prefix, String uri) throws SAXException {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}
